package com.boco.ibssystem.common.aop;

import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Aspect
@Component
public class RestControllerAspect {

    public static final String REQUEST_PARAMS = "REQUEST-PARAMS";

    @Around("@within(org.springframework.web.bind.annotation.RestController) || @annotation(org.springframework.web.bind.annotation.RestController) || @within(com.boco.ibssystem.common.result.support.ResponseResult) || @annotation(com.boco.ibssystem.common.result.support.ResponseResult)")
    public Object apiLog(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String params = getMethodParams(joinPoint);
        request.setAttribute(REQUEST_PARAMS, params);
        Object result = joinPoint.proceed();
        return result;
    }

    private static String getMethodParams(ProceedingJoinPoint joinPoint) {
        Object[] arguments = joinPoint.getArgs();
        StringBuilder sb = new StringBuilder();
        if (arguments == null || arguments.length <= 0) {
            return sb.toString();
        }
        for (Object arg : arguments) {
            //移除敏感内容
            String paramStr;
            if (arg instanceof HttpServletResponse) {
                paramStr = HttpServletResponse.class.getSimpleName();
            } else if (arg instanceof HttpServletRequest) {
                paramStr = HttpServletRequest.class.getSimpleName();
            } else if (arg instanceof MultipartFile) {
                long size = ((MultipartFile) arg).getSize();
                paramStr = MultipartFile.class.getSimpleName() + " size:" + size;
            } else {
                paramStr = convertObj2Str(arg);
            }
            sb.append(paramStr).append(",");
        }
        return sb.deleteCharAt(sb.length() - 1).toString();
    }

    private static String convertObj2Str(Object obj) {
        if (obj == null || obj instanceof Exception) {
            return "{}";
        }
        String param;
        try {
            param = JSONObject.toJSONString(obj);
        } catch (Exception e) {
            return String.valueOf(obj);
        }
        return param;
    }
}
